function flatten(obj) {
  let result = {};
  const flat = (obj, attr) => {
    let isObject = isPlainObject(obj), isArray = Array.isArray(obj);
    if (isObject || isArray) {
      if(isObject && isEmptyObject(obj)) {
        result[attr] = {};
        return;
      }
      each(obj, (value, key) => {
        let temp = isNaN(key)?`.${key}`:`[${key}]`;
        flat(value, !attr?key:attr+temp);
      })
      return;
    }
    result[attr] = obj;
  }
  flat(obj, '');
  return result
}